#include "game.h"
#include "ui_game.h"
#include "restart.h"
#include <algorithm> // for std::max
#include <cstdlib>   // for rand() and srand()

extern int offensiveMovePlayer;

game::game(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::game)
{
    initui();
    initpainter();
    initgame();

    // 初始化倒计时显示和定时器
    countdownDisplay = new QLCDNumber(this);
    countdownDisplay->setDigitCount(2);
    countdownDisplay->setGeometry(800, 10, 100, 40); // 设置位置和大小
    countdownDisplay->display(countdownTime);

    countdownTimer = new QTimer(this);
    connect(countdownTimer, &QTimer::timeout, this, &game::updateCountdown);
    countdownTimer->setInterval(1000); // 设置定时器每秒触发一次
}

game::~game() {
    delete ui;
    delete countdownTimer;
    delete countdownDisplay;
}

void game::initui() {
    ui->setupUi(this);
    QPalette pal(this->palette());
    QFont ft;
    this->setWindowTitle("五子棋");
    pal.setColor(QPalette::Window, QColor("#F9D65B")); // Use QPalette::Window here
    this->setAutoFillBackground(true);
    this->setPalette(pal);
    this->setFixedSize(1000,800);
    ui->lcdNumber->setDigitCount(3);
    ui->lcdNumber->setSegmentStyle(QLCDNumber::Flat);
    ui->label_4->resize(40,100);
    ui->label_4->setStyleSheet("color:red;");
    ft.setPointSize(14);
    ui->label_4->setFont(ft);
}

void game::initgame(){
    table=(chessman*)malloc((SIZE)*(SIZE)*sizeof(chessman));
    for(int i=0;i<SIZE*SIZE;i++){
        table[i].type=chessmanType::none;
    }
    chessPlayer=offensiveMovePlayer; // AI与玩家棋子相反
    gamemode=started;
    step=0;
    stepX.clear();
    stepY.clear();
    winner=none_win;
    drawChess=false;
}

void game::initpainter(){
    setMouseTracking(true);
    painter=new QPainter;
    painter->setRenderHint(QPainter::Antialiasing, true);
}

void game::paintEvent(QPaintEvent *)
{
    painter->begin(this);
    qDebug("MainOffensiveMovePlayer:%d",offensiveMovePlayer);

    painter->setPen(QPen(Qt::black,2,Qt::SolidLine));
    painter->setBrush(QBrush(Qt::black,Qt::SolidPattern));
    painter->drawEllipse(WIDTH*(SIZE+0.65)+20,yChessman,0.7*WIDTH,0.7*WIDTH);

    painter->setPen(QPen(Qt::white,2,Qt::SolidLine));
    painter->setBrush(QBrush(Qt::white,Qt::SolidPattern));
    painter->drawEllipse(WIDTH*(SIZE+2.65)+20,yChessman,0.7*WIDTH,0.7*WIDTH);

    painter->setPen(QPen(Qt::red,2,Qt::SolidLine));
    painter->setBrush(QBrush(Qt::red,Qt::SolidPattern));

    qDebug("%d",chessmanoffset);
    if(chessPlayer==playerblack){
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+selectXoffset-5,selectY+0.5*WIDTH-15);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH-5);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+selectXoffset+5,selectY+0.5*WIDTH+15);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH+5);

        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+selectXoffset-5,selectY+0.5*WIDTH+15);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+selectXoffset-15,selectY+0.5*WIDTH+5);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+selectXoffset+5,selectY+0.5*WIDTH-15);
        painter->drawLine(WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+selectXoffset+15,selectY+0.5*WIDTH-5);
    }else{
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-5,selectY+0.5*WIDTH-15);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH-5);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+5,selectY+0.5*WIDTH+15);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH+5);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-5,selectY+0.5*WIDTH+15);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH+15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset-15,selectY+0.5*WIDTH+5);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+5,selectY+0.5*WIDTH-15);
        painter->drawLine(WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH-15,WIDTH*(SIZE+1.15)+chessmanoffset+selectXoffset+15,selectY+0.5*WIDTH-5);
    }

    painter->setPen(QPen(Qt::darkGreen,2,Qt::SolidLine));
    for(int i=0;i<LINES+1;i++)
    {
        painter->drawLine(Start,Start+WIDTH*i,Start+WIDTH*LINES,Start+WIDTH*i);
        painter->drawLine(Start+WIDTH*i,Start,Start+WIDTH*i,Start+WIDTH*LINES);
    }

    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            chessman ch = get(j, i);
            if (ch.type == chessmanType::none) {
                printf("- ");
            }
            else if (ch.type == chessmanType::black) {
                printf("-B");
                painter->setPen(QPen(Qt::black,2,Qt::SolidLine));
                painter->setBrush(QBrush(Qt::black,Qt::SolidPattern));
                painter->drawEllipse((j-0.35)*WIDTH+20,(i-0.35)*WIDTH+20,0.7*WIDTH,0.7*WIDTH);
            }
            else {
                printf("-W");
                painter->setPen(QPen(Qt::white,2,Qt::SolidLine));
                painter->setBrush(QBrush(Qt::white,Qt::SolidPattern));
                painter->drawEllipse((j-0.35)*WIDTH+20,(i-0.35)*WIDTH+20,0.7*WIDTH,0.7*WIDTH);
            }
        }
        printf("\n");
    }
    printf("\n");

    if(gamemode==started){
        if(drawChess){
            if(chessPlayer==playerblack){
                painter->setPen(QPen(Qt::red,2,Qt::SolidLine));
                painter->setBrush(QBrush(Qt::black,Qt::SolidPattern));
                painter->drawEllipse((mouseX-0.35)*WIDTH+20,(mouseY-0.35)*WIDTH+20,0.7*WIDTH,0.7*WIDTH);
            }else{
                painter->setPen(QPen(Qt::red,2,Qt::SolidLine));
                painter->setBrush(QBrush(Qt::white,Qt::SolidPattern));
                painter->drawEllipse((mouseX-0.35)*WIDTH+20,(mouseY-0.35)*WIDTH+20,0.7*WIDTH,0.7*WIDTH);
            }
            drawChess=false;
        }
        painter->setPen(QPen(Qt::red,2,Qt::SolidLine));
        //选择框
        if(mouseX>=0 && mouseX< SIZE && mouseY >=0 && mouseY < SIZE){
            painter->drawLine((mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH-15,(mouseX+0.5)*WIDTH-5,(mouseY+0.5)*WIDTH-15);
            painter->drawLine((mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH-15,(mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH-5);
            painter->drawLine((mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH+15,(mouseX+0.5)*WIDTH+5,(mouseY+0.5)*WIDTH+15);
            painter->drawLine((mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH+15,(mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH+5);

            painter->drawLine((mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH+15,(mouseX+0.5)*WIDTH-5,(mouseY+0.5)*WIDTH+15);
            painter->drawLine((mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH+15,(mouseX+0.5)*WIDTH-15,(mouseY+0.5)*WIDTH+5);
            painter->drawLine((mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH-15,(mouseX+0.5)*WIDTH+5,(mouseY+0.5)*WIDTH-15);
            painter->drawLine((mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH-15,(mouseX+0.5)*WIDTH+15,(mouseY+0.5)*WIDTH-5);
        }
    }
    painter->end();
}

void game::mouseMoveEvent(QMouseEvent *event)
{
    int mx=event->x();
    int my=event->y();
    int x=(mx+WIDTH/2)/WIDTH;
    int y=(my+WIDTH/2-Start)/WIDTH;
    if((x!=mouseX || y!=mouseY) && x>=1 && x<=LINES && y>=1 && y<=LINES){
        mouseX=x;
        mouseY=y;
        if(gamemode!=started || get(mouseX,mouseY).type!=chessmanType::none){
            return;
        }
        print(mouseX,mouseY);
    }
}

void game::mouseReleaseEvent(QMouseEvent* event) {

    if (gamemode == started && mouseX >= 0 && mouseX < SIZE && mouseY >= 0 && mouseY < SIZE) {
    mouseX = (event->x()) / WIDTH;
    mouseY = (event->y()) / WIDTH;
    if (chessPlayer == playerblack) {
    putSucess = put(mouseX, mouseY, chessmanType::black);
    } else {
    putSucess = put(mouseX, mouseY, chessmanType::white);
    }
    if (putSucess) {
            chessPlayer = !chessPlayer;
        stepX.push_back(mouseX);
        stepY.push_back(mouseY);
        step++;
        ui->lcdNumber->display(step);

        startCountdown(); // 每次行动重置倒计时

        if (chessPlayer !=offensiveMovePlayer) {
            chessPlayer = !chessPlayer;
            makeAIMove(); // AI行动

        }
}
    print(mouseX, mouseY);
    winner = iswin();

    switch (iswin()) {
        case none_win:
            break;
        case white_win:
            msg("白方胜利");
            gamemode = gameover;
            break;
        case black_win:
            msg("黑方胜利");
            gamemode = gameover;
            break;
        case draw:
            msg("平局");
            gamemode = gameover;
            break;
    }
    }
    update();
}

void game::print(int x, int y)
{
    if(gamemode==started && get(x,y).type==chessmanType::none){
    drawChess=true;
    mouseX=x;
    mouseY=y;
    update();
    }
    }

    chessman game::get(int x, int y) {
    if (x < 1 || x > LINES || y < 1 || y > LINES) {
    chessman tmp;
    tmp.type = chessmanType::none;
    return tmp;
    }
    return table[(x - 1) *SIZE + (y - 1)];
}

int game::put(int x, int y, chessmanType type) {
    if (x >= 1 && x <= LINES && y >= 1 && y <= LINES && get(x, y).type == chessmanType::none) {
    table[(x - 1) * SIZE + (y - 1)].type = type;
    return 1;
    }
    return 0;
}

bool game::erase(int x, int y) {
    if (get(x, y).type != chessmanType::none) {
    table[(x - 1) * SIZE + (y - 1)].type = chessmanType::none;
    return true;
    }
    return false;
}

int game::iswin() {
    const int dx[] = {1, 0, 1, 1};
    const int dy[] = {0, 1, 1, -1};
    for (int x = 1; x <= LINES; x++) {
    for (int y = 1; y <= LINES; y++) {
    chessmanType t = get(x, y).type;
    if (t == chessmanType::none) continue;
    for (int d = 0; d < 4; d++) {
    int cnt = 1;
    for (int k = 1; k < 5; k++) {
    int nx = x + dx[d] * k;
    int ny = y + dy[d] * k;
    if (nx < 1 || ny < 1 || nx > LINES || ny > LINES || get(nx, ny).type != t) break;
    cnt++;
    }
    if (cnt >= 5) return t;
    }
    }
    }
    return none_win;
}

void game::delay_msec(unsigned int msec)
{
    QEventLoop loop;
    QTimer::singleShot(msec, &loop, SLOT(quit()));
    loop.exec();
    }

    void game::msg(QString q)
    {
    ui->label_4->setText(q);
    }

    void game::clearmsg()
    {
    ui->label_4->clear();
}

bool game::isAliveFour(int x, int y) {
        if (x < 2 || x > SIZE - 1 || y < 2 || y > SIZE - 1) {
            return false; // 边界检查，活四不可能出现在棋盘边缘
        }
        chessmanType currentType = get(x, y).type;
        // 检查当前位置是否为玩家的棋子
        if (currentType != (chessPlayer == playerblack ? chessmanType::black : chessmanType::white)) {
            return false;
        }
        // 检查四个方向是否都是当前玩家的棋子
        for (int dx : {-1, 0, 1}) {
            for (int dy : {-1, 1}) {
                int count = 0;
                for (int k = 0; k < 5; ++k) {
                    int nx = x + dx * k;
                    int ny = y + dy * k;
                    if (nx < 1 || nx > SIZE || ny < 1 || ny > SIZE || get(nx, ny).type != currentType) {
                        break;
                    }
                    ++count;
                }
                if (count == 4) {
                    return true; // 活四检测
                }
            }
        }
        return false; // 不是活四
    }

void game::makeAIMove() {
    int aiX, aiY;
    // 首先尝试阻止玩家的活四
    for (int i = 1; i < SIZE; ++i) {
        for (int j = 1; j < SIZE; ++j) {
            if (isAliveFour(i, j)) {
                // 如果发现活四，直接下在该位置阻断
                put(i, j, (chessPlayer == playerblack) ? chessmanType::white : chessmanType::black);
                stepX.push_back(i);
                stepY.push_back(j);
                step++;
                ui->lcdNumber->display(step);
                update();

            }
        }
    }

    // 如果没有发现活四，随机选择一个位置下棋
    do {
        aiX = rand() % SIZE + 1;
        aiY = rand() % SIZE + 1;
    } while (get(aiX, aiY).type != chessmanType::none);
    put(aiX, aiY, (chessPlayer == playerblack) ? chessmanType::white : chessmanType::black);

    stepX.push_back(aiX);
    stepY.push_back(aiY);
    step++;
    ui->lcdNumber->display(step);

    update(); // 重绘界面
}

void game::on_pushButton_3_clicked()
{
    initgame();
    gamemode=started;
    winner=none_win;
    step=0;
    stepX.clear();
    stepY.clear();
    update();
}

void game::on_pushButton_2_clicked()
{
    initgame();
    restartgame(false);
    update();
}

void game::on_pushButton_clicked()
{
    initgame();
    restartgame(true);
    update();
}

void game::restartgame(bool changeOffensiveMovePlayer)
{
    gamemode=started;
    winner=none_win;
    step=0;
    stepX.clear();
    stepY.clear();
    if(changeOffensiveMovePlayer){
    offensiveMovePlayer = (offensiveMovePlayer == playerblack) ? playerwhite : playerblack;
    }
    chessPlayer = offensiveMovePlayer;
    if (chessPlayer == playerwhite) {
    delay_msec(500);
    }
}

void game::startCountdown() {
    countdownTime = 10; // 重置倒计时时间
    countdownDisplay->display(countdownTime);
    countdownTimer->start(); // 启动定时器
}

void game::updateCountdown() {
    if (countdownTime > 0) {
    countdownTime--;
    countdownDisplay->display(countdownTime);
    } else {
    countdownTimer->stop(); // 停止定时器
    // 处理倒计时结束的逻辑，比如通知玩家时间到
    }
    if (countdownTime <= 0) {
    countdownDisplay->display("00:00"); // 显示时间到
    // 判断当前玩家的对方是否获胜
    if (chessPlayer == playerblack) {
        // 当前玩家是黑棋，则白棋获胜
        msg("白棋获胜！");
    } else {
        // 当前玩家是白棋，则黑棋获胜
        msg("黑棋获胜！");
    }

// 禁用游戏操作
    gamemode = gameover; // 设置游戏状态为结束

    }
}
